//
//  DMBannerStrategyParser.m
//  DualMediationSDK
//
//  Created by DualMediation on 2024/01/01.
//  Copyright © 2024 DualMediation. All rights reserved.
//

#import "DMBannerStrategyParser.h"
#import "../../Utils/Logger/IMLogUtils.h"
#import "../../API/AdStrategy/IMAdStrategyManager.h"

@interface DMBannerStrategyParser ()

/**
 * Banner策略数据缓存
 * 格式：{
 *   "SCENE_BANNER_INIT": {
 *     "ad_wait_time": 30,
 *     "ad_impression_pos": "bottom",
 *     "ad_banner_short_show": true,
 *     "ad_daily_limit": 10,
 *     "cur_level": 1,
 *     "ad_mob_first": false
 *   },
 *   "SCENE_BANNER_LEVEL_ENTER": {
 *     ...
 *   }
 * }
 */
@property (nonatomic, strong) NSMutableDictionary<NSString *, NSDictionary *> *bannerStrategies;

/**
 * 每日展示计数缓存
 * 格式：{
 *   "SCENE_BANNER_INIT_2024-01-01": 5,
 *   "SCENE_BANNER_LEVEL_ENTER_2024-01-01": 3
 * }
 */
@property (nonatomic, strong) NSMutableDictionary<NSString *, NSNumber *> *dailyShowCounts;

/**
 * 上次展示时间缓存
 * 格式：{
 *   "SCENE_BANNER_INIT": 1704067200.0,
 *   "SCENE_BANNER_LEVEL_ENTER": 1704067300.0
 * }
 */
@property (nonatomic, strong) NSMutableDictionary<NSString *, NSNumber *> *lastShowTimes;

@end

@implementation DMBannerStrategyParser

#pragma mark - 单例

+ (instancetype)sharedParser {
    static DMBannerStrategyParser *instance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[DMBannerStrategyParser alloc] init];
    });
    return instance;
}

- (instancetype)init {
    self = [super init];
    if (self) {
        _bannerStrategies = [NSMutableDictionary dictionary];
        _dailyShowCounts = [NSMutableDictionary dictionary];
        _lastShowTimes = [NSMutableDictionary dictionary];
        [self loadCachedData];
    }
    return self;
}

#pragma mark - 公共接口

- (BOOL)parseBannerStrategy:(NSDictionary *)strategyData {
    [IMLogUtils info:IMLogTagAd format:@"📋 开始解析Banner广告策略数据"];
    
    if (!strategyData || ![strategyData isKindOfClass:[NSDictionary class]]) {
        [IMLogUtils error:IMLogTagAd format:@"❌ Banner策略数据无效"];
        return NO;
    }
    
    @try {
        // 清除旧策略
        [self.bannerStrategies removeAllObjects];
        
        // 解析新策略
        for (NSString *sceneName in strategyData.allKeys) {
            NSDictionary *sceneConfig = strategyData[sceneName];
            if ([sceneConfig isKindOfClass:[NSDictionary class]]) {
                // 验证必要字段
                if ([self validateBannerConfig:sceneConfig forScene:sceneName]) {
                    self.bannerStrategies[sceneName] = [sceneConfig copy];
                    [IMLogUtils info:IMLogTagAd format:@"✅ 解析Banner场景策略成功 - %@", sceneName];
                } else {
                    [IMLogUtils warning:IMLogTagAd format:@"⚠️ Banner场景策略配置无效 - %@", sceneName];
                }
            }
        }
        
        [self saveCachedData];
        [IMLogUtils info:IMLogTagAd format:@"✅ Banner策略解析完成，共解析 %lu 个场景", (unsigned long)self.bannerStrategies.count];
        return YES;
        
    } @catch (NSException *exception) {
        [IMLogUtils error:IMLogTagAd format:@"❌ Banner策略解析异常: %@", exception.reason];
        return NO;
    }
}

- (nullable NSDictionary *)getBannerConfigForScene:(NSString *)sceneName {
    if (!sceneName || sceneName.length == 0) {
        [IMLogUtils error:IMLogTagAd format:@"❌ 获取Banner配置失败: 场景名称为空"];
        return nil;
    }
    
    NSDictionary *config = self.bannerStrategies[sceneName];
    if (config) {
        [IMLogUtils info:IMLogTagAd format:@"📋 获取Banner配置成功 - 场景: %@", sceneName];
    } else {
        [IMLogUtils warning:IMLogTagAd format:@"⚠️ 未找到Banner配置 - 场景: %@", sceneName];
    }
    
    return config;
}

- (BOOL)canShowBannerScene:(NSString *)sceneName 
              currentLevel:(NSInteger)currentLevel 
              lastShowTime:(NSTimeInterval)lastShowTime {
    
    [IMLogUtils info:IMLogTagAd format:@"🔍 检查Banner展示条件 - 场景: %@, 关卡: %ld", sceneName, (long)currentLevel];
    
    NSDictionary *config = [self getBannerConfigForScene:sceneName];
    if (!config) {
        [IMLogUtils warning:IMLogTagAd format:@"⚠️ 无Banner配置，允许展示 - 场景: %@", sceneName];
        return YES; // 无配置时默认允许展示
    }
    
    // 检查关卡条件
    NSNumber *requiredLevel = config[@"cur_level"];
    if (requiredLevel && currentLevel < requiredLevel.integerValue) {
        [IMLogUtils info:IMLogTagAd format:@"❌ 关卡不满足 - 当前: %ld, 需要: %ld", (long)currentLevel, (long)requiredLevel.integerValue];
        return NO;
    }
    
    // 检查等待时间
    NSInteger waitTime = [self getBannerWaitTimeForScene:sceneName];
    if (waitTime > 0) {
        NSTimeInterval currentTime = [[NSDate date] timeIntervalSince1970];
        NSTimeInterval lastShow = lastShowTime > 0 ? lastShowTime : [self getLastShowTimeForScene:sceneName];
        
        if (currentTime - lastShow < waitTime) {
            [IMLogUtils info:IMLogTagAd format:@"❌ 等待时间不满足 - 剩余: %.0f秒", waitTime - (currentTime - lastShow)];
            return NO;
        }
    }
    
    // 检查每日限制
    NSInteger dailyLimit = [self getBannerDailyLimitForScene:sceneName];
    if (dailyLimit > 0) {
        NSInteger todayCount = [self getTodayShowCountForScene:sceneName];
        if (todayCount >= dailyLimit) {
            [IMLogUtils info:IMLogTagAd format:@"❌ 每日限制已达 - 今日: %ld, 限制: %ld", (long)todayCount, (long)dailyLimit];
            return NO;
        }
    }
    
    [IMLogUtils info:IMLogTagAd format:@"✅ Banner展示条件满足 - 场景: %@", sceneName];
    return YES;
}

- (NSInteger)getBannerWaitTimeForScene:(NSString *)sceneName {
    NSDictionary *config = [self getBannerConfigForScene:sceneName];
    NSNumber *waitTime = config[@"ad_wait_time"];
    return waitTime ? waitTime.integerValue : -1;
}

- (nullable NSString *)getBannerPositionForScene:(NSString *)sceneName {
    NSDictionary *config = [self getBannerConfigForScene:sceneName];
    NSString *position = config[@"ad_impression_pos"];
    return position.length > 0 ? position : @"bottom"; // 默认底部
}

- (BOOL)isBannerShortShowEnabledForScene:(NSString *)sceneName {
    NSDictionary *config = [self getBannerConfigForScene:sceneName];
    NSNumber *shortShow = config[@"ad_banner_short_show"];
    return shortShow ? shortShow.boolValue : NO;
}

- (NSInteger)getBannerDailyLimitForScene:(NSString *)sceneName {
    NSDictionary *config = [self getBannerConfigForScene:sceneName];
    NSNumber *dailyLimit = config[@"ad_daily_limit"];
    return dailyLimit ? dailyLimit.integerValue : -1;
}

- (BOOL)isAdMobFirstForScene:(NSString *)sceneName {
    NSDictionary *config = [self getBannerConfigForScene:sceneName];
    NSNumber *adMobFirst = config[@"ad_mob_first"];
    return adMobFirst ? adMobFirst.boolValue : NO;
}

- (void)clearAllStrategies {
    [IMLogUtils info:IMLogTagAd format:@"🗑️ 清除所有Banner策略缓存"];
    [self.bannerStrategies removeAllObjects];
    [self.dailyShowCounts removeAllObjects];
    [self.lastShowTimes removeAllObjects];
    [self saveCachedData];
}

#pragma mark - 私有方法

/**
 * 验证Banner配置的有效性
 */
- (BOOL)validateBannerConfig:(NSDictionary *)config forScene:(NSString *)sceneName {
    // 基本类型检查
    if (![config isKindOfClass:[NSDictionary class]]) {
        return NO;
    }
    
    // 可选字段验证
    NSArray *optionalKeys = @[@"ad_wait_time", @"ad_impression_pos", @"ad_banner_short_show", 
                             @"ad_daily_limit", @"cur_level", @"ad_mob_first"];
    
    for (NSString *key in config.allKeys) {
        if (![optionalKeys containsObject:key]) {
            [IMLogUtils warning:IMLogTagAd format:@"⚠️ 未知Banner配置字段: %@ - 场景: %@", key, sceneName];
        }
    }
    
    return YES;
}

/**
 * 获取今日展示次数
 */
- (NSInteger)getTodayShowCountForScene:(NSString *)sceneName {
    NSString *todayKey = [self getTodayKeyForScene:sceneName];
    NSNumber *count = self.dailyShowCounts[todayKey];
    return count ? count.integerValue : 0;
}

/**
 * 增加今日展示次数
 */
- (void)incrementTodayShowCountForScene:(NSString *)sceneName {
    NSString *todayKey = [self getTodayKeyForScene:sceneName];
    NSInteger currentCount = [self getTodayShowCountForScene:sceneName];
    self.dailyShowCounts[todayKey] = @(currentCount + 1);
    [self saveCachedData];
}

/**
 * 获取上次展示时间
 */
- (NSTimeInterval)getLastShowTimeForScene:(NSString *)sceneName {
    NSNumber *lastTime = self.lastShowTimes[sceneName];
    return lastTime ? lastTime.doubleValue : 0;
}

/**
 * 更新上次展示时间
 */
- (void)updateLastShowTimeForScene:(NSString *)sceneName {
    NSTimeInterval currentTime = [[NSDate date] timeIntervalSince1970];
    self.lastShowTimes[sceneName] = @(currentTime);
    [self incrementTodayShowCountForScene:sceneName];
    [self saveCachedData];
}

/**
 * 获取今日缓存键
 */
- (NSString *)getTodayKeyForScene:(NSString *)sceneName {
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    formatter.dateFormat = @"yyyy-MM-dd";
    NSString *today = [formatter stringFromDate:[NSDate date]];
    return [NSString stringWithFormat:@"%@_%@", sceneName, today];
}

/**
 * 加载缓存数据
 */
- (void)loadCachedData {
    // TODO: 从本地存储加载缓存数据
    // 这里可以使用NSUserDefaults或其他持久化方案
    [IMLogUtils info:IMLogTagAd format:@"📋 加载Banner策略缓存数据"];
}

/**
 * 保存缓存数据
 */
- (void)saveCachedData {
    // TODO: 保存缓存数据到本地存储
    // 这里可以使用NSUserDefaults或其他持久化方案
    [IMLogUtils info:IMLogTagAd format:@"💾 保存Banner策略缓存数据"];
}

#pragma mark - 策略获取接口

- (void)fetchAndParseBannerStrategyWithCompletion:(void(^)(BOOL success, NSError * _Nullable error))completion {
    [IMLogUtils info:IMLogTagAd format:@"🔄 开始从广告策略接口获取Banner策略数据"];
    
    if (!completion) {
        [IMLogUtils error:IMLogTagAd format:@"❌ fetchAndParseBannerStrategyWithCompletion: completion回调为空"];
        return;
    }
    
    // 获取IMAdStrategyManager实例
    IMAdStrategyManager *strategyManager = [IMAdStrategyManager sharedManager];
    if (!strategyManager) {
        NSError *error = [NSError errorWithDomain:@"DMBannerStrategyParser" 
                                             code:-1001 
                                         userInfo:@{NSLocalizedDescriptionKey: @"无法获取IMAdStrategyManager实例"}];
        [IMLogUtils error:IMLogTagAd format:@"❌ 无法获取IMAdStrategyManager实例"];
        completion(NO, error);
        return;
    }
    
    // 从策略管理器获取Banner相关策略
    @try {
        // 获取SCENE_BANNER_INIT场景的策略
        NSDictionary *bannerInitStrategy = [strategyManager getConditionForScene:IMAdSceneBannerInit];
        
        // 获取SCENE_BANNER_LEVEL_ENTER场景的策略
        NSDictionary *bannerLevelEnterStrategy = [strategyManager getConditionForScene:IMAdSceneBannerLevelEnter];
        
        // 构建Banner策略数据
        NSMutableDictionary *bannerStrategies = [NSMutableDictionary dictionary];
        
        if (bannerInitStrategy && [bannerInitStrategy isKindOfClass:[NSDictionary class]]) {
            bannerStrategies[@"SCENE_BANNER_INIT"] = bannerInitStrategy;
            [IMLogUtils info:IMLogTagAd format:@"✅ 获取SCENE_BANNER_INIT策略成功"];
        }
        
        if (bannerLevelEnterStrategy && [bannerLevelEnterStrategy isKindOfClass:[NSDictionary class]]) {
            bannerStrategies[@"SCENE_BANNER_LEVEL_ENTER"] = bannerLevelEnterStrategy;
            [IMLogUtils info:IMLogTagAd format:@"✅ 获取SCENE_BANNER_LEVEL_ENTER策略成功"];
        }
        
        // 解析获取到的策略数据
        BOOL parseSuccess = [self parseBannerStrategy:bannerStrategies];
        
        if (parseSuccess) {
            [IMLogUtils info:IMLogTagAd format:@"✅ Banner策略获取和解析成功"];
            completion(YES, nil);
        } else {
            NSError *error = [NSError errorWithDomain:@"DMBannerStrategyParser" 
                                                 code:-1002 
                                             userInfo:@{NSLocalizedDescriptionKey: @"Banner策略解析失败"}];
            [IMLogUtils error:IMLogTagAd format:@"❌ Banner策略解析失败"];
            completion(NO, error);
        }
        
    } @catch (NSException *exception) {
        NSError *error = [NSError errorWithDomain:@"DMBannerStrategyParser" 
                                             code:-1003 
                                         userInfo:@{NSLocalizedDescriptionKey: [NSString stringWithFormat:@"获取Banner策略异常: %@", exception.reason]}];
        [IMLogUtils error:IMLogTagAd format:@"❌ 获取Banner策略异常: %@", exception.reason];
        completion(NO, error);
    }
}

@end